package pers.jphoebe.quartz.controller;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import pers.jphoebe.quartz.entity.JobAndTrigger;
import pers.jphoebe.quartz.job.BaseJob;
import pers.jphoebe.quartz.service.IJobAndTriggerService;
import com.github.pagehelper.PageInfo;
import springfox.documentation.annotations.ApiIgnore;


@RestController
@RequestMapping(value="/job")
@ApiIgnore
public class JobController 
{
	@Autowired
	private IJobAndTriggerService iJobAndTriggerService;

	@Autowired
	private Scheduler scheduler;

	private static Logger log = LoggerFactory.getLogger(JobController.class);  

	@PostMapping(value="/addjob")
	public void addjob(@RequestParam(value="jobClassName")String jobClassName, 
			@RequestParam(value="jobGroupName")String jobGroupName, 
			@RequestParam(value="cronExpression")String cronExpression,
		   @RequestParam(value = "jobDescription")String jobDescription) throws Exception
	{			
		addJob(jobClassName, jobGroupName, cronExpression,jobDescription);
	}
	
	public void addJob(String jobClassName, String jobGroupName, String cronExpression,String jobDescription)throws Exception{
		try {
			if(StringUtils.isEmpty(jobClassName)&&
					StringUtils.isEmpty(jobGroupName)&&
					StringUtils.isEmpty(cronExpression)&&
					StringUtils.isEmpty(jobDescription)){
				jobClassName = "pers.jphoebe.quartz.job.GsiPriceJob";
				jobGroupName = "job";
				cronExpression = "0 0 9,14 * * ? *";
				jobDescription = "定时刷新金银价格";
			}
			if(StringUtils.isEmpty(jobClassName)||
					StringUtils.isEmpty(jobGroupName)||
					StringUtils.isEmpty(cronExpression)||
					StringUtils.isEmpty(jobDescription)){
				return;
			}

			//构建job信息
			JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass())
					.withIdentity(jobClassName, jobGroupName)
					.withDescription(jobDescription)
					.build();
			//表达式调度构建器(即任务执行的时间)
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
			//按新的cronExpression表达式构建一个新的trigger
			CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName)
				.withSchedule(scheduleBuilder).build();

			scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
			e.printStackTrace();
            System.out.println("创建定时任务失败"+e);
            throw new Exception("创建定时任务失败");
        }
	}


	@PostMapping(value="/pausejob")
	public void pausejob(@RequestParam(value="jobClassName")String jobClassName, @RequestParam(value="jobGroupName")String jobGroupName) throws Exception
	{			
		jobPause(jobClassName, jobGroupName);
	}
	
	public void jobPause(String jobClassName, String jobGroupName) throws Exception
	{
		scheduler.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));
	}
	

	@PostMapping(value="/resumejob")
	public void resumejob(@RequestParam(value="jobClassName")String jobClassName, @RequestParam(value="jobGroupName")String jobGroupName) throws Exception
	{			
		jobresume(jobClassName, jobGroupName);
	}
	
	public void jobresume(String jobClassName, String jobGroupName) throws Exception
	{
		scheduler.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));
	}
	
	
	@PostMapping(value="/reschedulejob")
	public void rescheduleJob(@RequestParam(value="jobClassName")String jobClassName, 
			@RequestParam(value="jobGroupName")String jobGroupName,
			@RequestParam(value="cronExpression")String cronExpression,
		    @RequestParam(value = "jobDescription")String jobDescription) throws Exception
	{			
		jobreschedule(jobClassName, jobGroupName, cronExpression,jobDescription);
	}
	
	public void jobreschedule(String jobClassName, String jobGroupName, String cronExpression,String jobDescription) throws Exception
	{				
		try {

			TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
			// 表达式调度构建器
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

			// 按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder()
					.withIdentity(triggerKey)
					.withSchedule(scheduleBuilder)
					.withDescription(jobDescription)
					.build();

			// 按新的trigger重新设置job执行
			scheduler.rescheduleJob(triggerKey, trigger);
		} catch (SchedulerException e) {
			System.out.println("更新定时任务失败"+e);
			throw new Exception("更新定时任务失败");
		}
	}
	
	
	@PostMapping(value="/deletejob")
	public void deletejob(@RequestParam(value="jobClassName")String jobClassName, @RequestParam(value="jobGroupName")String jobGroupName) throws Exception
	{			
		jobdelete(jobClassName, jobGroupName);
	}
	
	public void jobdelete(String jobClassName, String jobGroupName) throws Exception
	{
		scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));
		scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));
		scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
	}
	
	
	@GetMapping(value="/queryjob")
	public Map<String, Object> queryjob(@RequestParam(value="pageNum")Integer pageNum, @RequestParam(value="pageSize")Integer pageSize) 
	{			
		PageInfo<JobAndTrigger> jobAndTrigger = iJobAndTriggerService.getJobAndTriggerDetails(pageNum, pageSize);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("JobAndTrigger", jobAndTrigger);
		map.put("number", jobAndTrigger.getTotal());
		return map;
	}
	
	public BaseJob getClass(String classname) throws Exception
	{
		Class<?> class1 = Class.forName(classname);
		return (BaseJob)class1.newInstance();
	}
	
	
}

